# @Time : 2021/4/23 14:53
# @Author : Fioman 
# @Phone : 13149920693
import time

import gevent

from db_tools.db_handler import DbHandler
from tools.config_params import ConfigParams
from tools.send_to_ui_tools import send_line_camera_joint_state
from tools.common_tools import image_to_string
from vision_process.image_transfer import get_joint_image
from vision_process.image_operation import *
from tools.save_image_to_device import *

"""
上料相机拼接工具
"""

cp = ConfigParams()
# 图像拼接的类,根据原始图像获取拼接之后的图像,包括型材的截取,还有拼接的位置.
class ImageJointTool(object):
    def __init__(self, leftCam, rightCam, camZmc):
        self.db = DbHandler()
        self.logger = HdLogger()
        self.reload_image_joint_params()
        self.leftCam = leftCam
        self.rightCam = rightCam
        self.camZmc = camZmc
        self.leftImg = None
        self.rightImg = None

    def reload_image_joint_params(self):
        """
        图像拼接参数加载
        :return:
        """
        res, imageJointParams = self.db.get_image_joint_params()
        if res == "ok":
            self.leftCamStartOffset = int(imageJointParams.get("leftCamStartOffset"))  # 左相机的左边截掉的像素数
            self.leftCamEndOffset = int(imageJointParams.get("leftCamEndOffset"))  # 左相机右边截掉的像素数
            self.rightCamStartOffset = int(imageJointParams.get("rightCamStartOffset"))  # 右相机左边截掉的像素数
            self.rightCamEndOffset = int(imageJointParams.get("rightCamEndOffset"))  # 右相机右边截掉的像素数
            self.leftCamHOffset = int(imageJointParams.get("leftCamHOffset"))  # 左相机的高度移动的像素数,负数表示上移,正数表示向下移动

    @staticmethod
    def web_request_open_image_joint_dir():
        """
        前端界面点击查看拼接图片的按钮
        :return:
        """
        ret = os.system("explorer.exe {}".format(IMAGE_JOINT_DIR))
        return "ok" if ret == 1 else ret

    def web_request_save_image_joint_params(self, newData):
        """
        前端界面点击保存图像拼接参数
        :param newData:新的值
        :return:
        """
        res, info = self.db.save_image_joint_params(newData)
        if res == "ok":
            self.reload_image_joint_params()
            if self.leftImg is not None and self.rightImg is not None:
                *_, leftMean = find_single_image_material_area(self.leftImg)
                *_, rightMean = find_single_image_material_area(self.rightImg)
                jointImage = get_joint_image(self.leftImg, self.rightImg)
                _, boxMaster, _ = find_single_image_material_area(jointImage)
                writeInfo = ["Val = {}".format(leftMean), "Val = {}".format(rightMean)]
                writePos = "leftAndRight"
                jointImageColor = write_board_info_to_image(jointImage, boxMaster, writePos, writeInfo)
                imgSend = image_to_string(jointImageColor)
                msgValue = {
                    "val": "updateJointImage",
                    "jointImageSrc": imgSend
                }
                send_line_camera_joint_state(msgValue)
        return "ok" if res == "ok" else info

    def web_request_get_move_joint_image(self, newData):
        """
        前端界面移动图像的时候调用的函数
        :param newData:
        :return:
        """
        newData = [int(x) for x in newData]
        leftCamStartMove, leftCamEndMove, rightCamStartMove, rightCamEndMove, leftCamHMove = newData
        self.leftCamStartOffset += leftCamStartMove
        self.leftCamEndOffset += leftCamEndMove
        self.rightCamStartOffset += rightCamStartMove
        self.rightCamEndOffset += rightCamEndMove
        self.leftCamHOffset += leftCamHMove
        newValue = {
            "leftCamStartOffset": self.leftCamStartOffset if self.leftCamStartOffset > 0 else 0,
            "leftCamEndOffset": self.leftCamEndOffset if self.leftCamEndOffset > 0 else 0,
            "rightCamStartOffset": self.rightCamStartOffset if self.rightCamStartOffset > 0 else 0,
            "rightCamEndOffset": self.rightCamEndOffset if self.rightCamEndOffset > 0 else 0,
            "leftCamHOffset": self.leftCamHOffset
        }
        res, info = self.db.save_image_joint_params(newValue)
        if res == "ok":
            msgValue = {
                "val": "updateJointParams"
            }
            send_line_camera_joint_state(msgValue)
            *_, leftMean = find_single_image_material_area(self.leftImg)
            *_, rightMean = find_single_image_material_area(self.rightImg)
            jointImage = get_joint_image(self.leftImg, self.rightImg)
            _, boxMaster, _ = find_single_image_material_area(jointImage)
            writeInfo = ["Val = {}".format(leftMean), "Val = {}".format(rightMean)]
            writePos = "leftAndRight"
            jointImageColor = write_board_info_to_image(jointImage, boxMaster, writePos, writeInfo)
            imgSend = image_to_string(jointImageColor)
            msgValue = {
                "val": "updateJointImage",
                "jointImageSrc": imgSend
            }
            send_line_camera_joint_state(msgValue)
            # 保存拼接完的图片
            fileName = "{}.bmp".format(get_time_now_string())
            filePath = os.path.join(IMAGE_JOINT_DIR, fileName)
            delete_exist_index_image(IMAGE_JOINT_DIR, "joint")
            cv.imwrite(filePath, jointImage)
            return "ok"
        else:
            return info

    def web_request_get_image_for_image_joint(self):
        """
        上料点击抓取图片,这个时候要一直检测15信号,如果没有收到这个信号,就要提示前端,错误信息.
        :return:
        """
        start = time.time()
        while True:
            if time.time() - start > 30:
                errorInfo = "未检测到有板信号bit(15)=1,请确保来料到位,并且在传感器的位置上."
                self.send_error_message_to_ui(errorInfo, "noBoard")
                return None
            ret, val = self.camZmc.get_allow_get_pic_state()
            if ret != 0:
                self.send_error_message_to_ui(ret, "camZmc")
                return None

            if val == 1:
                break
            else:
                gevent.sleep(0.5)
                continue
        if val == 1:
            res, jointImage = self.get_image_from_line_cam()
            fileName = "{}.bmp".format(get_time_now_string())
            cv.imwrite(os.path.join(IMAGE_JOINT_DIR, fileName), jointImage)
            if res != "ok":
                self.send_error_message_to_ui(res, "cameraError")
                return None
            else:
                # 将拼接后的图像处理一下发送给前端
                *_, leftMean = find_single_image_material_area(self.leftImg)
                *_, rightMean = find_single_image_material_area(self.rightImg)
                _, boxMaster, _ = find_single_image_material_area(jointImage)
                writeInfo = ["Val = {}".format(leftMean), "Val = {}".format(rightMean)]
                writePos = "leftAndRight"
                jointImageColor = write_board_info_to_image(jointImage, boxMaster, writePos, writeInfo)
                imgSend = image_to_string(jointImageColor)
                msgValue = {
                    "val": "updateJointImage",
                    "jointImageSrc": imgSend
                }
                send_line_camera_joint_state(msgValue)
                return "ok"

    def web_request_re_get_image_for_image_joint(self):
        """
        上料相机拼接工具那里点击重新拍照的按钮的逻辑
        :return:
        """
        ret = self.camZmc.img_result_failed()
        if ret != 0:
            self.send_error_message_to_ui(ret, "camZmc")
            return None
        while True:
            ret, val = self.camZmc.get_allow_get_pic_state()
            if ret != 0:
                self.send_error_message_to_ui(ret, "camZmc")
                return None

            if val == 1:
                break
            else:
                gevent.sleep(0.5)
                continue

        if val == 1:
            res, jointImage = self.get_image_from_line_cam()
            if res != "ok":
                self.send_error_message_to_ui(res, "cameraError")
                return None
            else:
                fileName = "{}.bmp".format(get_time_now_string())
                cv.imwrite(os.path.join(IMAGE_JOINT_DIR, fileName), jointImage)
                # 将拼接后的图像处理一下发送给前端
                *_, leftMean = find_single_image_material_area(self.leftImg)
                *_, rightMean = find_single_image_material_area(self.rightImg)
                _, boxMaster, _ = find_single_image_material_area(jointImage)
                writeInfo = ["Val = {}".format(leftMean), "Val = {}".format(rightMean)]
                writePos = "leftAndRight"
                jointImageColor = write_board_info_to_image(jointImage, boxMaster, writePos, writeInfo)
                imgSend = image_to_string(jointImageColor)
                msgValue = {
                    "val": "updateJointImage",
                    "jointImageSrc": imgSend
                }
                send_line_camera_joint_state(msgValue)
                return "ok"

    def web_request_reset_cam_zmc(self):
        """
        点击复位上料按钮
        :return:
        """
        self.camZmc.cam_zmc_stop()
        ret = self.camZmc.cam_zmc_reset()
        return "ok" if ret == 0 else ret

    def re_start_line_camera(self):
        """
        重新打开线阵相机
        :return:
        """
        self.leftCam.stop_grabbing()
        self.rightCam.stop_grabbing()
        gevent.sleep(1)
        self.leftCam.start_grabbing()
        self.rightCam.start_grabbing()

    def get_image_from_line_cam(self):
        """
        从线阵相机里获取图片相机获取图片
        :return:
        """
        self.leftCam.clear_buffer()
        self.rightCam.clear_buffer()
        ret = self.camZmc.set_allow_take_pic()
        if ret != 0:
            return "上料控制器通信异常", None
        self.camZmc.clear_allow_get_pic_state()
        self.camZmc.clear_img_result_failed()
        retLeft, leftImage = self.leftCam.get_image_line()
        if retLeft != 0:
            return "左相机获取图片失败: {}".format(leftImage), None
        retRight, rightImage = self.rightCam.get_image_line()
        if retRight != 0:
            return "右相机获取图片失败: {}".format(rightImage), None
        self.leftImg, self.rightImg = leftImage, rightImage
        jointImage = get_joint_image(self.leftImg, self.rightImg)
        return "ok", jointImage

    @staticmethod
    def send_error_message_to_ui(msgInfo, errorType):
        """
        将一些后台的错误消息发送给前端,并且展示到日志当中去
        :param msgInfo: 错误的消息内容
        :param errorType: 错误的消息类型
        :return:
        """
        if errorType == "camZmc":
            msgInfo = "上料控制器通信读写异常,请检查电源线和网线是否连接正常!"
        msgValue = {
            "val": "errorShow",
            "errorInfo": msgInfo,
        }
        send_line_camera_joint_state(msgValue)

    def web_reqeust_check_mm_to_pix(self):
        """
        前端界面点击了验证高宽比和像素比
        :return:
        """
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = configParams
            return errorInfo
        mm2pix = configParams.get("mm2pix")

        res, imageJointParams = self.db.get_image_joint_params()
        if res != "ok":
            return imageJointParams
        else:
            inputWidth = imageJointParams.get("inputWidth")
            inputHeight = imageJointParams.get("inputHeight")
        if inputWidth == 0 or inputHeight == 0 or inputWidth is None or inputHeight is None:
            return "录入的尺寸不能为0,请先录入尺寸"
        self.inputWidth = float(inputWidth)
        self.inputHeight = float(inputHeight)

        fileNames = []
        for root, dirs, files in os.walk(COUNT_BOARD_SIZE_DIR):
            if root != COUNT_BOARD_SIZE_DIR:
                continue
            for file in files:
                if file[-4:] != ".bmp" or "res" in file:
                    continue
                else:
                    fileNames.append(file)

        # 如果文件名字为空
        if len(fileNames) == 0:
            return "没有要计算的文件,请先拍摄8张图片用于计算"
        # 这里开始计算
        self.TotalBoardList = []
        self.boardOkImageList = []
        self.boardOkSizeList = []
        self.lastPicFlag = False
        for index, fileName in enumerate(fileNames):
            imageSrc = cv.imread(os.path.join(COUNT_BOARD_SIZE_DIR, fileName), cv.IMREAD_GRAYSCALE)
            _, boxMaster, _ = find_single_image_material_area(imageSrc)
            writePos = "imageNum"
            writeInfo = "{}".format(index + 1)
            totalBoardImage = write_board_info_to_image(imageSrc, boxMaster, writePos, writeInfo)
            delete_exist_index_image(COUNT_BOARD_SIZE_DIR, "{}".format(index + 1))
            cv.imwrite(os.path.join(COUNT_BOARD_SIZE_DIR, "{}--res.bmp".format(index + 1)), totalBoardImage)
            boardWith, boardHeight = [round(x, 3) for x in boxMaster[1]]
            self.TotalBoardList.append([totalBoardImage, [boardWith, boardHeight]])
        else:
            self.sendIndex = 0
            imageSend = self.TotalBoardList[self.sendIndex][0]
            imageSend = image_to_string(imageSend)
            boardSize = self.TotalBoardList[self.sendIndex][1]
            boardSize = [round(x / mm2pix, 3) for x in boardSize]  # 转换为mm
            checkError = [round(boardSize[0] - self.inputWidth, 3), round(boardSize[1] - self.inputHeight, 3)]
            boardInfo = "第 {} 张图,识别结果:宽 = {} ,高 = {}".format(self.sendIndex + 1, boardSize[0], boardSize[1])
            msgValue = {
                "val": "updateCheckSizeImageSrc",
                "checkSizeImageSrc": imageSend,
                "inputSize": [self.inputWidth, self.inputHeight],
                "checkSize": boardSize,
                "checkError": checkError,
                "checkInfo": boardInfo
            }
            send_line_camera_joint_state(msgValue)
            return "ok"

    def web_request_check_size_ok(self):
        """
        前端界面点击了确认物料框查找ok
        :return:
        """
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = configParams
            return errorInfo
        mm2pix = configParams.get("mm2pix")

        if not self.lastPicFlag:
            self.boardOkImageList.append(self.TotalBoardList[self.sendIndex][0])
            self.boardOkSizeList.append(self.TotalBoardList[self.sendIndex][1])
        self.sendIndex += 1
        boardInfo = ""
        if self.sendIndex == len(self.TotalBoardList):
            self.sendIndex -= 1
            boardInfo = "已经是最后一张"
            self.lastPicFlag = True
        imageSend = self.TotalBoardList[self.sendIndex][0]
        imageSend = image_to_string(imageSend)
        boardSize = self.TotalBoardList[self.sendIndex][1]
        boardSize = [round(x / mm2pix, 3) for x in boardSize]  # 转换为mm
        checkError = [round(boardSize[0] - self.inputWidth, 3), round(boardSize[1] - self.inputHeight, 3)]
        boardInfo += "第 {} 张图,识别结果:宽 = {} ,高 = {}".format(self.sendIndex + 1, boardSize[0], boardSize[1])
        msgValue = {
            "val": "updateCheckSizeImageSrc",
            "checkSizeImageSrc": imageSend,
            "inputSize": [self.inputWidth, self.inputHeight],
            "checkSize": boardSize,
            "checkError": checkError,
            "checkInfo": boardInfo
        }
        send_line_camera_joint_state(msgValue)
        return "ok"

    def web_request_check_size_error(self):
        """
        前端界面点击物料尺寸不OK,失败调用的逻辑
        :return:
        """
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = configParams
            return errorInfo
        mm2pix = configParams.get("mm2pix")
        self.sendIndex += 1
        boardInfo = ""
        if self.sendIndex == len(self.TotalBoardList):
            self.sendIndex -= 1
            boardInfo = "已经是最后一张"
            self.lastPicFlag = True
        imageSend = self.TotalBoardList[self.sendIndex][0]
        imageSend = image_to_string(imageSend)
        boardSize = self.TotalBoardList[self.sendIndex][1]
        boardSize = [round(x / mm2pix, 3) for x in boardSize]  # 转换为mm
        checkError = [round(boardSize[0] - self.inputWidth, 3), round(boardSize[1] - self.inputHeight, 3)]
        boardInfo += "第 {} 张图,识别结果:宽 = {} ,高 = {}".format(self.sendIndex + 1, boardSize[0], boardSize[1])
        msgValue = {
            "val": "updateCheckSizeImageSrc",
            "checkSizeImageSrc": imageSend,
            "inputSize": [self.inputWidth, self.inputHeight],
            "checkSize": boardSize,
            "checkError": checkError,
            "checkInfo": boardInfo
        }
        send_line_camera_joint_state(msgValue)
        return "ok"

    def web_request_count_board_size(self):
        """
        前端界面点击了计算高宽比和像素比.
        :return:
        """
        res, imageJointParams = self.db.get_image_joint_params()
        if res != "ok":
            return imageJointParams
        else:
            inputWidth = imageJointParams.get("inputWidth")
            inputHeight = imageJointParams.get("inputHeight")
        if inputWidth == 0 or inputHeight == 0 or inputWidth is None or inputHeight is None:
            return "录入的尺寸不能为0,请先录入尺寸"
        self.inputWidth = float(inputWidth)
        self.inputHeight = float(inputHeight)

        fileNames = []
        for root, dirs, files in os.walk(COUNT_BOARD_SIZE_DIR):
            if root != COUNT_BOARD_SIZE_DIR:
                continue
            for file in files:
                if file[-4:] != ".bmp" or "res" in file:
                    continue
                else:
                    fileNames.append(file)

        # 如果文件名字为空
        if len(fileNames) == 0:
            return "没有要计算的文件,请先拍摄8张图片用于计算"

        # 这里开始计算
        self.TotalBoardList = []
        self.boardOkImageList = []
        self.boardOkSizeList = []
        self.lastPicFlag = False
        for index, fileName in enumerate(fileNames):
            imageSrc = cv.imread(os.path.join(COUNT_BOARD_SIZE_DIR, fileName), cv.IMREAD_GRAYSCALE)
            _, boxMaster, _ = find_single_image_material_area(imageSrc)
            writePos = "imageNum"
            writeInfo = "{}".format(index + 1)
            totalBoardImage = write_board_info_to_image(imageSrc, boxMaster, writePos, writeInfo)
            delete_exist_index_image(COUNT_BOARD_SIZE_DIR, "{}".format(index + 1))
            cv.imwrite(os.path.join(COUNT_BOARD_SIZE_DIR, "{}--res.bmp".format(index + 1)), totalBoardImage)
            boardWith, boardHeight = [round(x, 3) for x in boxMaster[1]]
            self.TotalBoardList.append([totalBoardImage, [boardWith, boardHeight]])
        else:
            self.sendIndex = 0
            imageSend = self.TotalBoardList[self.sendIndex][0]
            imageSend = image_to_string(imageSend)
            boardSize = self.TotalBoardList[self.sendIndex][1]
            boardInfo = "第 {} 张图,识别结果:宽 = {} ,高 = {}".format(self.sendIndex + 1, boardSize[0], boardSize[1])
            msgValue = {
                "val": "updateCountWidthHeightImage",
                "countWidthHeightImgSrc": imageSend,
                "boardSize": boardSize,
                "inputSize": [self.inputWidth, self.inputHeight],
                "showInfo": boardInfo
            }
            send_line_camera_joint_state(msgValue)
            return "ok"

    def web_request_total_board_is_ok(self):
        """
        前端界面点击物料查找ok,保存当前的ok尺寸
        :return:
        """
        if not self.lastPicFlag:
            self.boardOkImageList.append(self.TotalBoardList[self.sendIndex][0])
            self.boardOkSizeList.append(self.TotalBoardList[self.sendIndex][1])
        self.sendIndex += 1
        boardInfo = ""
        if self.sendIndex == len(self.TotalBoardList):
            self.sendIndex -= 1
            boardInfo = "已经是最后一张"
            self.lastPicFlag = True
        imageSend = self.TotalBoardList[self.sendIndex][0]
        imageSend = image_to_string(imageSend)
        boardSize = self.TotalBoardList[self.sendIndex][1]
        boardInfo += "第 {} 张图,识别结果:宽 = {} ,高 = {}".format(self.sendIndex + 1, boardSize[0], boardSize[1])
        msgValue = {
            "val": "updateCountWidthHeightImage",
            "countWidthHeightImgSrc": imageSend,
            "boardSize": boardSize,
            "inputSize": [self.inputWidth, self.inputHeight],
            "showInfo": boardInfo
        }
        send_line_camera_joint_state(msgValue)
        return "ok"

    def web_request_total_board_is_error(self):
        """
        前端界面点击物料查找ok,保存当前的ok尺寸
        :return:
        """
        self.sendIndex += 1
        boardInfo = ""
        if self.sendIndex == len(self.TotalBoardList):
            self.sendIndex -= 1
            boardInfo = "已经是最后一张! "
        imageSend = self.TotalBoardList[self.sendIndex][0]
        imageSend = image_to_string(imageSend)
        boardSize = self.TotalBoardList[self.sendIndex][1]
        boardInfo += "第 {} 张图,识别结果:宽 = {} ,高 = {}".format(self.sendIndex + 1, boardSize[0], boardSize[1])
        msgValue = {
            "val": "updateCountWidthHeightImage",
            "countWidthHeightImgSrc": imageSend,
            "inputSize": [self.inputWidth, self.inputHeight],
            "boardSize": boardSize,
            "showInfo": boardInfo
        }
        send_line_camera_joint_state(msgValue)
        return "ok"

    def web_request_save_mm_to_pix(self):
        """
        前端界面点击保存计算的像素比和高宽比
        :return:
        """
        try:
            newData = {
                "heightWidthRatio": self.newHeightWidthRatio,
                "mm2pix": self.newMm2pix,
            }
            res, info = self.db.save_config_params(newData)
            cp.reload_config_params()
        except Exception as e:
            errorInfo = "in ImageJointTool.web_request_save_mm_to_pix() error: {}".format(str(e))
            print(errorInfo)
            self.logger.debug(errorInfo)
            return errorInfo
        return "ok" if res == "ok" else info

    def web_request_calc_mm_to_pix(self):
        """
        前端界面点击计算像素比调用的逻辑
        :return:
        """
        res, imageJointParams = self.db.get_image_joint_params()
        if res != "ok":
            return imageJointParams
        else:
            inputWidth = imageJointParams.get("inputWidth")
            inputHeight = imageJointParams.get("inputHeight")
        if inputWidth == 0 or inputHeight == 0 or inputWidth is None or inputHeight is None:
            return "录入的尺寸不能为0,请先录入尺寸"
        self.inputWidth = float(inputWidth)
        self.inputHeight = float(inputHeight)

        # 第一步,计算所使用的所有宽度,所有高度,还有平均宽度,平均高度.
        self.widthUsedList = [size[0] for size in self.boardOkSizeList]
        self.heightUsedList = [size[1] for size in self.boardOkSizeList]
        widthMean = round(int(np.mean(self.widthUsedList)), 4)
        heightMean = round(int(np.mean(self.heightUsedList)), 4)
        mm2pix = round(widthMean / inputWidth, 5)
        mm2pixHeight = round(heightMean / inputHeight, 5)
        # 这里计算新的高宽比.
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        heightWidthRatioOld = configParams.get("heightWidthRatio")
        self.newHeightWidthRatio = round(heightWidthRatioOld / (mm2pixHeight / mm2pix), 5)
        self.newMm2pix = mm2pix
        imageSend = self.TotalBoardList[self.sendIndex][0]
        imageSend = image_to_string(imageSend)
        boardSize = [widthMean, heightMean]
        showInfo = "使用宽度: {},使用高度: {} ,像素比: {},高宽比: {}".format(self.widthUsedList, self.heightUsedList,
                                                               self.newMm2pix, self.newHeightWidthRatio)
        msgValue = {
            "val": "updateCountWidthHeightImage",
            "countWidthHeightImgSrc": imageSend,
            "boardSize": boardSize,
            "inputSize": [self.inputWidth, self.inputHeight],
            "showInfo": showInfo
        }
        send_line_camera_joint_state(msgValue)
        return "ok"

    def web_request_save_total_board_size(self, inputSize):
        """
        界面上点击了保存物料的尺寸的逻辑.
        :return:
        """
        inputSize = [float(x) for x in inputSize]
        inputWidth, inputHeight = inputSize
        newData = {
            "inputWidth": inputWidth,
            "inputHeight": inputHeight
        }
        res, info = self.db.save_image_joint_params(newData)
        if res == "ok":
            self.inputWidth = inputWidth
            self.inputHeight = inputHeight
        return "ok" if res == "ok" else info

    @staticmethod
    def web_request_open_count_board_size_dir():
        """
        界面上点击了查看图片的按钮
        :return:
        """
        return open_count_board_size_dir()

    def web_request_calc_check_error(self):
        """
        界面上点击了计算平均误差的逻辑
        :return:
        """
        query = {
            "key": "1"
        }
        res, configParams = self.db.get_data_one(self.db.configParamsTable, query)
        if res != "ok":
            errorInfo = configParams
            return errorInfo
        mm2pix = configParams.get("mm2pix")
        res, imageJointParams = self.db.get_image_joint_params()
        if res != "ok":
            return imageJointParams
        else:
            inputWidth = imageJointParams.get("inputWidth")
            inputHeight = imageJointParams.get("inputHeight")
        if inputWidth == 0 or inputHeight == 0 or inputWidth is None or inputHeight is None:
            return "录入的尺寸不能为0,请先录入尺寸"
        self.inputWidth = float(inputWidth)
        self.inputHeight = float(inputHeight)

        self.widthUsedList = [size[0] for size in self.boardOkSizeList]
        self.heightUsedList = [size[1] for size in self.boardOkSizeList]
        widthMean = round(np.mean(self.widthUsedList) / mm2pix, 4)
        heightMean = round(np.mean(self.heightUsedList) / mm2pix, 4)
        imageSend = self.TotalBoardList[self.sendIndex][0]
        imageSend = image_to_string(imageSend)
        boardSize = [widthMean, heightMean]
        meanError = [round(widthMean - self.inputWidth, 3), round(heightMean - self.inputHeight, 3)]
        showInfo = "使用宽度: {},使用高度: {} ,平均误差: {}".format(self.widthUsedList, self.heightUsedList, meanError)
        msgValue = {
            "val": "updateCheckSizeImageSrc",
            "checkSizeImageSrc": imageSend,
            "inputSize": [self.inputWidth, self.inputHeight],
            "checkSize": boardSize,
            "checkError": meanError,
            "checkInfo": showInfo
        }
        send_line_camera_joint_state(msgValue)
        return "ok"

    def web_request_get_eight_image_for_count(self):
        """
        前端界面点击拍8张图用于统计.如何去搞定这件事,先急停复位.然后复位完成以后,再启动.怎么检测复位完成呢,复位完成以后bit位会置为0
        :return:
        """
        self.camZmc.cam_zmc_rs_stop()
        time.sleep(0.2)
        self.camZmc.cam_zmc_reset()
        time.sleep(1)
        while True:
            val = self.camZmc.is_reset_state()[1]
            if val == 0:
                break  # 等待复位状态完成.
        # 复位完成启动设备
        self.camZmc.cam_zmc_start()
        # 启动成功以后,开始记录拍摄次数,遍历文件夹,删除所有的文件
        for root, dirs, files in os.walk(COUNT_BOARD_SIZE_DIR):
            if root != COUNT_BOARD_SIZE_DIR:
                continue
            for file in files:
                os.remove(os.path.join(COUNT_BOARD_SIZE_DIR, file))

        # 删除所有的文件以后,开始检测拍照信号
        getImageTimes = 1
        while getImageTimes <= 8:
            _, val = self.camZmc.get_allow_get_pic_state()
            if val == 0:
                continue
            self.camZmc.clear_allow_get_pic_state()  # 清楚允许拍照的信号
            self.camZmc.clear_img_result_failed()  # 清除重拍的信号
            res, image = self.get_image_from_line_cam()  # 清除拍照失败的信号
            if res == "ok":
                keepFileName = "{}.bmp".format(get_time_now_string())
                cv.imwrite(os.path.join(COUNT_BOARD_SIZE_DIR, keepFileName), image)
                getImageTimes += 1
            self.camZmc.img_result_failed()
        return "ok"

    # def test_new_function(self):
    #     """
    #     测试新的功能,前端界面点击这里.可以测试新功能.
    #     :return:
    #     """
    #     self.send_joint_image_to_web()

    def web_requset_close_cam_zmc_door_alarm(self):
        """
        前端界面点击了屏蔽上料门报警
        :return:
        """
        ret = self.camZmc.close_door_alarm()
        return "ok" if ret == 0 else ret

    def send_joint_image_to_web(self):
        """
        获取拼接的图像,然后返回给前端,测试的时候使用.
        :return:
        """
        leftFileName = "left_original.bmp"
        rightFileName = "right_original.bmp"
        self.leftImg = cv.imread(os.path.join(IMAGE_JOINT_DIR, leftFileName), cv.IMREAD_GRAYSCALE)
        self.rightImg = cv.imread(os.path.join(IMAGE_JOINT_DIR, rightFileName), cv.IMREAD_GRAYSCALE)
        *_, leftMean = find_single_image_material_area(self.leftImg)
        *_, rightMean = find_single_image_material_area(self.rightImg)
        jointImage = get_joint_image(self.leftImg, self.rightImg)
        _, boxMaster, _ = find_single_image_material_area(jointImage)
        writeInfo = ["Val = {}".format(leftMean), "Val = {}".format(rightMean)]
        writePos = "leftAndRight"
        jointImageColor = write_board_info_to_image(jointImage, boxMaster, writePos, writeInfo)
        imgSend = image_to_string(jointImageColor)
        msgValue = {
            "val": "updateJointImage",
            "jointImageSrc": imgSend
        }
        send_line_camera_joint_state(msgValue)
